/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 * Description: Little Test Audio Project - 音频采集、处理和播放项目头文件
 */

#ifndef LITTLE_TEST_H
#define LITTLE_TEST_H

#include <stdint.h>
#include <stdbool.h>
#include "opus.h"
#include "i2s.h"
#include "dma.h"
#include "osal_task.h"
#include "osal_semaphore.h"
#include "osal_msgqueue.h"

#ifdef __cplusplus
extern "C" {
#endif

/* 音频配置参数 */
#define LITTLE_TEST_SAMPLE_RATE     16000   // 采样率 16kHz
#define LITTLE_TEST_CHANNELS        1       // 单声道
#define LITTLE_TEST_FRAME_SIZE      960     // 每帧样本数 (60ms at 16kHz)
#define LITTLE_TEST_BUFFER_COUNT    4       // 循环缓冲区数量
#define LITTLE_TEST_BUFFER_SIZE     (LITTLE_TEST_FRAME_SIZE * 2)  // 缓冲区大小（字节）
#define LITTLE_TEST_OPUS_BITRATE    32000   // Opus编码比特率
#define LITTLE_TEST_MAX_PACKET_SIZE 4000    // 最大Opus包大小

/* DMA配置参数 */
#define LITTLE_TEST_DMA_PRIORITY    DMA_PRIORITY_HIGH
#define LITTLE_TEST_DMA_BURST_LEN   DMA_BURST_LENGTH_8
#define LITTLE_TEST_DMA_DATA_WIDTH  DMA_DATA_WIDTH_16

/* I2S配置参数 */
#define LITTLE_TEST_I2S_MODE        I2S_MODE_MASTER
#define LITTLE_TEST_I2S_TRANS_MODE  I2S_TRANS_MODE_STD
#define LITTLE_TEST_I2S_DATA_WIDTH  I2S_DATA_WIDTH_16
#define LITTLE_TEST_I2S_CLK_EDGE    I2S_CLK_EDGE_RISE

/* 任务优先级和栈大小 */
#define LITTLE_TEST_TASK_PRIORITY   24
#define LITTLE_TEST_TASK_STACK_SIZE 4096

/* 队列大小 */
#define LITTLE_TEST_ENCODE_QUEUE_SIZE 8
#define LITTLE_TEST_DECODE_QUEUE_SIZE 8

/* 音频数据结构 */
typedef struct {
    int16_t *data;              // 音频数据指针
    uint32_t size;              // 数据大小（样本数）
    uint32_t timestamp;         // 时间戳
    bool is_valid;              // 数据有效标志
} audio_frame_t;

/* 循环缓冲区结构 */
typedef struct {
    int16_t *buffer;            // 缓冲区数据
    uint32_t size;              // 缓冲区大小（样本数）
    uint32_t write_index;       // 写入索引
    uint32_t read_index;        // 读取索引
    bool is_full;               // 缓冲区满标志
    osal_semaphore *sem_read;   // 读信号量
    osal_semaphore *sem_write;  // 写信号量
} circular_buffer_t;

/* Opus编解码器结构 */
typedef struct {
    OpusEncoder *encoder;       // Opus编码器
    OpusDecoder *decoder;       // Opus解码器
    uint8_t *encode_buffer;     // 编码缓冲区
    int16_t *decode_buffer;     // 解码缓冲区
    bool initialized;           // 初始化标志
} opus_codec_t;

/* 编码数据包结构 */
typedef struct {
    uint8_t *data;              // 编码数据
    uint32_t size;              // 数据大小
    uint32_t timestamp;         // 时间戳
} encoded_packet_t;

/* 音频采集模块结构 */
typedef struct {
    uint8_t dma_channel;        // DMA通道
    circular_buffer_t *buffers; // 循环缓冲区数组
    uint32_t current_buffer;    // 当前缓冲区索引
    bool is_running;            // 运行状态
    osal_task *task;            // 采集任务
} audio_capture_t;

/* 音频播放模块结构 */
typedef struct {
    uint8_t dma_channel;        // DMA通道
    circular_buffer_t *buffers; // 循环缓冲区数组
    uint32_t current_buffer;    // 当前缓冲区索引
    bool is_running;            // 运行状态
    osal_task *task;            // 播放任务
} audio_playback_t;

/* 音频处理模块结构 */
typedef struct {
    osal_task *preprocess_task; // 预处理任务
    osal_task *encode_task;     // 编码任务
    osal_task *decode_task;     // 解码任务
    osal_msgqueue *encode_queue; // 编码队列
    osal_msgqueue *decode_queue; // 解码队列
    opus_codec_t codec;         // Opus编解码器
    bool is_running;            // 运行状态
} audio_processing_t;

/* 主控制结构 */
typedef struct {
    audio_capture_t capture;    // 音频采集模块
    audio_playback_t playback;  // 音频播放模块
    audio_processing_t processing; // 音频处理模块
    bool initialized;           // 初始化标志
    bool is_running;            // 运行状态
} little_test_context_t;

/* 函数声明 */

/* 主控制函数 */
int little_test_init(void);
void little_test_deinit(void);
int little_test_start(void);
void little_test_stop(void);

/* 循环缓冲区函数 */
int circular_buffer_init(circular_buffer_t *cb, uint32_t size);
void circular_buffer_deinit(circular_buffer_t *cb);
int circular_buffer_write(circular_buffer_t *cb, const int16_t *data, uint32_t size);
int circular_buffer_read(circular_buffer_t *cb, int16_t *data, uint32_t size);
bool circular_buffer_is_full(const circular_buffer_t *cb);
bool circular_buffer_is_empty(const circular_buffer_t *cb);
uint32_t circular_buffer_available_write(const circular_buffer_t *cb);
uint32_t circular_buffer_available_read(const circular_buffer_t *cb);

/* 音频采集函数 */
int audio_capture_init(audio_capture_t *capture);
void audio_capture_deinit(audio_capture_t *capture);
int audio_capture_start(audio_capture_t *capture);
void audio_capture_stop(audio_capture_t *capture);
void audio_capture_dma_callback(uint8_t channel, uintptr_t arg);

/* 音频播放函数 */
int audio_playback_init(audio_playback_t *playback);
void audio_playback_deinit(audio_playback_t *playback);
int audio_playback_start(audio_playback_t *playback);
void audio_playback_stop(audio_playback_t *playback);
void audio_playback_dma_callback(uint8_t channel, uintptr_t arg);

/* 音频处理函数 */
int audio_processing_init(audio_processing_t *processing);
void audio_processing_deinit(audio_processing_t *processing);
int audio_processing_start(audio_processing_t *processing);
void audio_processing_stop(audio_processing_t *processing);

/* Opus编解码函数 */
int opus_codec_init(opus_codec_t *codec);
void opus_codec_deinit(opus_codec_t *codec);
int opus_encode_frame(opus_codec_t *codec, const int16_t *pcm, uint8_t *encoded, uint32_t max_size);
int opus_decode_frame(opus_codec_t *codec, const uint8_t *encoded, uint32_t encoded_size, int16_t *pcm);

/* 音频预处理函数 */
void audio_preprocess_mono(const int16_t *input, int16_t *output, uint32_t samples);
void audio_remove_dc_offset(int16_t *data, uint32_t samples);
void audio_apply_gain(int16_t *data, uint32_t samples, float gain);

#ifdef __cplusplus
}
#endif

#endif /* LITTLE_TEST_H */